﻿using System;
using System.IO;

namespace SharpTag.ID3
{
    /// <summary>
    /// Concreate implementation of the <see cref="ITagReader"/> interface.
    /// </summary>
    public class ID3V2TagReader : ITagReader
    {
        private const int ID3V2TagHeaderLength = 10;
        private const int ID3V2TagHeaderSizeOffset = 6;
        private const int ID3V2TagHeaderSizeLength = 4;
        private const int ID3IdLength = 3;
        private BinaryReader br;

        /// <summary>
        /// Reads the ID3v2 tag information from a file.
        /// </summary>
        /// <param name="taggedFile">The <see cref="IFile"/> object.</param>
        /// <returns>A byte array containg the ID3v2 tag information.</returns>
        public byte[] ReadTagBytes(IFile taggedFile)
        {
            var tagHeaderBytes = new byte[ID3V2TagHeaderLength];
            br = new BinaryReader(File.Open(taggedFile.Path, FileMode.Open, FileAccess.Read, FileShare.None));
            br.Read(tagHeaderBytes, 0, ID3V2TagHeaderLength);
            var idChar = new char[ID3IdLength];
            Array.Copy(tagHeaderBytes, 0, idChar, 0, ID3IdLength);
            
            var idString = new string(idChar);
            if (string.Compare(idString, "ID3", true) == 0)
            {
                var sizeBytes = new byte[ID3V2TagHeaderSizeLength];
                Array.Copy(tagHeaderBytes, ID3V2TagHeaderSizeOffset, sizeBytes, 0, ID3V2TagHeaderSizeLength);
                var size = sizeBytes.CalcualteSyncSafeSize();

                br.BaseStream.Seek(0, SeekOrigin.Begin);

                // Size reported in tag header does not include the header itself.
                var tagBytes = br.ReadBytes((int)size + ID3V2TagHeaderLength);
                br.Close();

                return tagBytes;
            }

            br.Close();
            return null;
        }
    }
}
